# -*- coding: utf-8 -*-
# @Time    : 2019/5/15 20:17
# @Author  : Igor
# @File    : 递归锁.py
# @Software: PyCharm
# @递归锁和解决死锁

# ---------------死锁--------------------------------
import threading
import time

mutexA = threading.Lock()   #把threading下Lock类赋值给mutexA
mutexB = threading.Lock()   #把threading下Lock类赋值给mutexB


class MyThread(threading.Thread):   #定义MyThread类 并继承threading下的Thread类功能

    def __init__(self):     #初始化实例化
        threading.Thread.__init__(self)   #初始父类实例化

    def run(self):     #定义run函数 （此函数是固定函数）
        self.fun1()    #实例化对象引用执行fun1函数
        self.fun2()    #实例化对象引用执行fun2函数

    def fun1(self):    #定义fun1函数

        mutexA.acquire()  # 获取公共锁，如果锁被占用,则阻塞在这里,等待锁的释放

        print("I am %s , get res: %s---%s" % (self.name, "ResA", time.time()))

        mutexB.acquire()  # 获取公共锁，如果锁被占用,则阻塞在这里,等待锁的释放
        print("I am %s , get res: %s---%s" % (self.name, "ResB", time.time()))
        mutexB.release()  # 释放公共锁

        mutexA.release()  # 释放公共锁


    def fun2(self):   #定义fun2函数

        mutexB.acquire()  # 获取公共锁，如果锁被占用,则阻塞在这里,等待锁的释放
        print("I am %s , get res: %s---%s" % (self.name, "ResB", time.time()))
        time.sleep(0.2)

        mutexA.acquire()  # 获取公共锁，如果锁被占用,则阻塞在这里,等待锁的释放
        print("I am %s , get res: %s---%s" % (self.name, "ResA", time.time()))
        mutexA.release()  # 释放公共锁

        mutexB.release()  # 释放公共锁


if __name__ == "__main__":

    print("start---------------------------%s" % time.time())

    for i in range(0, 10):
        my_thread = MyThread()
        my_thread.start()

"""
运行结果
start---------------------------1494320240.1851542
I am Thread-1 , get res: ResA---1494320240.1856549
I am Thread-1 , get res: ResB---1494320240.1861556
I am Thread-1 , get res: ResB---1494320240.1861556
I am Thread-2 , get res: ResA---1494320240.186656
死锁了
"""


# -------------递归锁解决死锁的情况------------------
import threading
import time

RLock = threading.RLock()   # 把threading下RLock类赋值给RLock


class MyThread(threading.Thread):   # 定义MyThread类 并继承threading下的Thread类功能

    def __init__(self):
        threading.Thread.__init__(self)   #初始父类实例化

    def run(self):     #定义run函数 （此函数是固定函数）
        self.fun1()    #实例化对象引用执行fun1函数
        self.fun2()    #实例化对象引用执行fun2函数

    def fun1(self):

        RLock.acquire()  # 获取公共锁，如果锁被占用,则阻塞在这里,等待锁的释放

        print("I am %s , na res: %s---%s" % (self.name, "ResA", time.time()))

        RLock.acquire()  # 获取公共锁，如果锁被占用,则阻塞在这里,等待锁的释放
        print("I am %s , na res: %s---%s" % (self.name, "ResB", time.time()))
        RLock.release()  # 释放公共锁

        RLock.release()  # 释放公共锁


    def fun2(self):   #定义fun2函数

        RLock.acquire()  # 获取公共锁，如果锁被占用,则阻塞在这里,等待锁的释放
        print("I am %s , na res: %s---%s" % (self.name, "ResB", time.time()))
        time.sleep(0.2)

        RLock.acquire()  # 获取公共锁，如果锁被占用,则阻塞在这里,等待锁的释放
        print("I am %s , na res: %s---%s" % (self.name, "ResA", time.time()))
        RLock.release()  # 释放公共锁

        RLock.release()  # 释放公共锁


if __name__ == "__main__":

    print("start---------------------------%s" % time.time())

    for i in range(0, 10):
        my_thread = MyThread()
        my_thread.start()
